package cn.edu.xjtu.nbrash.xbarsuite.floatbutton;

import java.io.FileNotFoundException;
import java.io.IOException;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import cn.edu.xjtu.nbrash.xbarsuite.R;
import cn.edu.xjtu.nbrash.xbarsuite.RashIntents;
import cn.edu.xjtu.nbrash.xbarsuite.result.RashResultActivity;
import cn.edu.xjtu.nbrash.xbarsuite.utilities.Utilities;

import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;

public class FloatButtonService extends IntentService {

	private static final String TAG = FloatButtonService.class.getName();

	public static final String ACTION_FLOAT_BUTTON = "cn.edu.xjtu.nbrash.xbarsuite.FloatButton";
	public static final String ACTION_REMOVE_FLOAT_BUTTON = "cn.edu.xjtu.nbrash.xbarsuite.RemoveFloatButton";
	public static final String ACTION_SCREEN_SHOT_AND_DECODER = "cn.edu.xjtu.nbrash.xbarsuite.ScreenShot&Decoder";
	public static final String ACTION_DECODER = "cn.edu.xjtu.nbrash.xbarsuite.Decoder";

	private static final int DEFAULT_RETRY_TIMES = 1;
	public static final String EXTRA_RETRY = "cn.edu.xjtu.nbrash.xbarsuite.RetryTimes";
	private static final String DECODER_PREFERENCES = "_decoder_preferences";

	/**
	 * 增加一个按钮点击事件的时间间隙，默认5秒
	 */
	private static final long DEFAULT_CLICK_GAP = 6180L;
	private static long lastClick = 0L;

	/**
	 * 再来个状态助助兴
	 */
	private static FloatButtonStatus status = FloatButtonStatus.Idle;

	public static enum FloatButtonStatus {
		Idle, Busy
	}

	public static boolean isFloatButtonExist() {
		return FloatButtonCreator
				.containsFloatButton(RashIntents.FloatButton.FLOAT_BUTTON_FLAG);
	}

	public static synchronized void startActionRemoveFloatButton(
			final Context context) {
		Intent intent = new Intent(context, FloatButtonService.class);
		intent.setAction(ACTION_REMOVE_FLOAT_BUTTON);
		context.startService(intent);
	}

	/**
	 * 启动一个FloatButton的Service， 此Service仅仅用于添加FloatButton，且只添加至多一个。
	 * 
	 * @param context
	 */
	public static synchronized void startActionFloatButton(final Context context) {
		Intent intent = new Intent(context, FloatButtonService.class);
		intent.setAction(ACTION_FLOAT_BUTTON);
		context.startService(intent);

		SharedPreferences sharePreferences = context.getSharedPreferences(
				RashIntents.FloatButton.FLOAT_BUTTON_PREFERENCES,
				Context.MODE_PRIVATE);
		int x = sharePreferences.getInt(
				RashIntents.FloatButton.FLOAT_BUTTON_POSITION_X, 0);
		int y = sharePreferences.getInt(
				RashIntents.FloatButton.FLOAT_BUTTON_POSITION_Y, 0);
		float alpha = sharePreferences.getFloat(
				RashIntents.FloatButton.FLOAT_BUTTON_ALPHA,
				RashIntents.FloatButton.DEFAULT_FLOAT_BUTTON_ALPHA);
		FloatButtonCreator.createFloatButtonByResource(
				RashIntents.FloatButton.FLOAT_BUTTON_FLAG,
				context.getApplicationContext(),
				R.drawable.floatbutton_selector, 100, 100, x, y, alpha);

		FloatButtonCreator.getFloatButton(
				RashIntents.FloatButton.FLOAT_BUTTON_FLAG)
				.setFloatButtonOnClickListener(
						new FloatButtonOnClickListener() {
							@Override
							public void onClick() {
								FloatButtonService
										.startActionScreenshotAndDecoder(context
												.getApplicationContext());
							}
						});
	}

	/**
	 * 不知道为什么要用线程安全，感觉萌萌的
	 * 
	 * @param context
	 */
	public static synchronized void startActionScreenshotAndDecoder(
			Context context) {
		if (getStatus().equals(FloatButtonStatus.Idle)) {
			long currentClick = System.currentTimeMillis();
			if (currentClick - lastClick > DEFAULT_CLICK_GAP) {
				setStatus(FloatButtonStatus.Busy);
				lastClick = currentClick;
				Intent intent = new Intent(context, FloatButtonService.class);
				intent.setAction(ACTION_SCREEN_SHOT_AND_DECODER);
				context.startService(intent);
			} else {
				Toast.makeText(context, "点击过频，注意节制", Toast.LENGTH_SHORT).show();
			}
		} else {
			Toast.makeText(context, "服务正忙，请稍后", Toast.LENGTH_SHORT).show();
		}
	}

	public FloatButtonService() {
		super("FloatButtonService");
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		if (intent != null) {
			final String action = intent.getAction();
			if (ACTION_FLOAT_BUTTON.equals(action)) {
				handleActionFloatButton();
			} else if (ACTION_SCREEN_SHOT_AND_DECODER.equals(action)) {
				handleActionScreenShot();
			} else if (ACTION_DECODER.equals(action)) {
				handleActionDecoder(intent.getData(),
						intent.getIntExtra(EXTRA_RETRY, DEFAULT_RETRY_TIMES));
			} else if (ACTION_REMOVE_FLOAT_BUTTON.equals(action)) {
				handleActionRemoveFloatButton();
			}
		}
	}

	private void handleActionFloatButton() {

	}

	private void handleActionRemoveFloatButton() {
		SharedPreferences sharePreferences = getSharedPreferences(
				RashIntents.FloatButton.FLOAT_BUTTON_PREFERENCES,
				Context.MODE_PRIVATE);
		FloatButton floatButton = FloatButtonCreator
				.getFloatButton(RashIntents.FloatButton.FLOAT_BUTTON_FLAG);
		sharePreferences
				.edit()
				.putInt(RashIntents.FloatButton.FLOAT_BUTTON_POSITION_X,
						floatButton.getLayoutParams().x)
				.putInt(RashIntents.FloatButton.FLOAT_BUTTON_POSITION_Y,
						floatButton.getLayoutParams().y)
				.putFloat(RashIntents.FloatButton.FLOAT_BUTTON_ALPHA,
						floatButton.getLayoutParams().alpha).commit();
		FloatButtonCreator
				.removeFloatButton(RashIntents.FloatButton.FLOAT_BUTTON_FLAG);
	}

	private void handleActionScreenShot() {
		String tempPath = getBaseContext().getFilesDir().getPath()
				+ "/temp.screenshot.png";

		Uri screenshot = ScreenShotUtil.takeScreenShot(tempPath);

		if (screenshot != null) {
			handleActionDecoder(screenshot, 0);
		} else {
			Log.e(TAG, "Screenshot Failed!");
		}
	}

	private void handleActionDecoder(Uri uri, int retry) {
		Bitmap bitmap = null;
		Result result = null;

		SharedPreferences sp = getBaseContext().getSharedPreferences(
				DECODER_PREFERENCES, MODE_PRIVATE);
		int maxRetryTimes = sp.getInt(EXTRA_RETRY, DEFAULT_RETRY_TIMES);

		try {
			// 从Uri获取Bitmap对象，会抛出FileNotFound以及IO异常
			bitmap = MediaStore.Images.Media.getBitmap(getBaseContext()
					.getContentResolver(), uri);
			// 解码，会抛出NotFound异常
			result = new MultiFormatReader().decode(Utilities
					.bitmap2BinaryBitmap(bitmap));

		} catch (FileNotFoundException e) {
			Log.e(TAG, e.toString());
		} catch (IOException e) {
			Log.e(TAG, e.toString());
		} catch (NotFoundException e) {
			Log.e(TAG, e.toString());
			if (retry < maxRetryTimes) {
				// Crop the image, and decode again
				Intent intent = new Intent(getApplicationContext(),
						RashCropActivity.class);
				intent.setAction(RashCropActivity.ACTION_CROP);
				intent.setData(uri);
				intent.putExtra(EXTRA_RETRY, retry);
				intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				startActivity(intent);
				return;
			}
		}

		String text = result != null ? result.getText() : null;
		Intent intent = new Intent(getApplicationContext(),
				RashResultActivity.class);
		// 扩展：历史记录
		// if (result != null) {
		// Uri crop = getResultImage(bitmap, result.getResultPoints()[1],
		// result.getResultPoints()[2], result.getResultPoints()[0]);
		// intent.setData(crop);
		// }
		intent.putExtra(RashIntents.Result.EXTRA_Result, text);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
				| Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
		startActivity(intent);
		Log.e(TAG, text != null ? text : "null");
		setStatus(FloatButtonStatus.Idle);
	}

	/**
	 * 裁剪图片得到二维码，用以存储历史信息 三点剪裁图片
	 * 
	 * 图像太大，先保存到本地再说
	 * 
	 * @param source
	 * 
	 *            点的分布, 从左到右，p0,p1,从上到下，p0,p2，三点即可
	 * 
	 * @param p0
	 * @param p1
	 * @param p2
	 * @return
	 * @hide
	 */
	@SuppressWarnings("unused")
	private Uri getResultImage(Bitmap source, ResultPoint p0, ResultPoint p1,
			ResultPoint p2) {

		String tempPath = getBaseContext().getFilesDir().getPath()
				+ "/temp.result.png";

		int maxWidth = source.getWidth();
		int maxHeight = source.getHeight();
		int x = (int) p0.getX();
		int y = (int) p0.getY();
		int width = (int) (p1.getX() - x);
		int height = (int) (p2.getY() - y);
		x -= (width / 4);
		if (x < 0) {
			x = 0;
		}
		y -= (height / 4);
		if (y < 0) {
			y = 0;
		}
		width *= 1.5;
		if (width > (maxWidth - x)) {
			width = maxWidth - x;
		}
		height *= 1.5;
		if (height > (maxHeight - y)) {
			height = maxHeight - y;
		}
		Bitmap bitmap = Bitmap.createBitmap(source, x, y, width, height);

		return Utilities.bitmap2Uri(tempPath, bitmap);
	}

	public static FloatButtonStatus getStatus() {
		return status;
	}

	public static synchronized void setStatus(FloatButtonStatus status) {
		FloatButtonService.status = status;
	}

}
